package org.subside.Lambda;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;

/**
 * @Author : zhangbo
 * @data : 2024/6/12
 * @description :
 */
public class MyLambda {
    /**
     * 一、函数式接口的概念
     * 函数式接口是指只包含一个抽象方法的接口。在Java中，函数式接口被用于支持函数式编程的特性，
     * 它可以用作Lambda表达式的类型、方法引用的类型或者函数式接口的实例化。
     *
     * 函数式接口具有以下特点：
     * 只包含一个抽象方法，但可以包含默认方法和静态方法。
     * 可以使用@FunctionalInterface注解进行标识，以确保它符合函数式接口的规范。
     * Java提供了许多函数式接口，如Runnable、Consumer、Predicate等。这些接口在函数式编程中扮演重要的角色，
     * 能够简化代码的编写，并提供更加灵活的函数组合方式。
     */
    /**
     * 函数式接口的语法非常简单，只需要定义一个抽象方法即可
     * MyInterface是一个函数式接口，只包含一个抽象方法myMethod()。使用@FunctionalInterface注解可以确保这个接口只包含一个抽象方法
     */
    @FunctionalInterface
    interface MyInterface {
        void myMethod();
    }

    /**
     * 函数式接口例子
     */
    Runnable runnable = () -> {
        System.out.println("Hello, Functional Interface!");
    };
    Consumer<String> consumer = name -> {
        System.out.println("Hello, " + name + "!");
    };
    Predicate<Integer> isEven = number -> number % 2 == 0;

    /**
     *
     * 基本概念
     * Lambda 表达式：是一个匿名函数，可以作为参数传递给方法。
     * 参数列表：Lambda 表达式的参数列表，可以省略括号。
     * 箭头符号 (->)：分隔参数列表和 Lambda 体。
     * Lambda 体：Lambda 表达式的执行部分，可以是一个表达式或一个代码块。
     */

    /**
     * Runnable：表示一个没有参数和返回值的操作。
     * Consumer<T>：表示接受一个参数并执行某些操作，没有返回值。
     * Supplier<T>：表示一个提供对象的操作，没有参数。
     * Function<T, R>：表示接受一个参数并返回结果的操作。
     * Predicate<T>：表示接受一个参数并返回布尔值的操作。
     */

    /**
     *语法结构
     * Lambda 表达式的一般语法结构如下
     */
    //1.(parameters) -> { /* 代码块 */ }
    //或者，如果只有一个参数，可以省略参数类型和括号
    //2.parameter -> { /* 代码块 */ }
    //或者，如果 Lambda 体只有一个表达式，可以省略大括号
    //(parameters) -> expression
    public static void main(String[] args) {
        //使用 Lambda 表达式打印数组元素
        int[] numbers = {1, 2, 3, 4, 5};
        Arrays.stream(numbers).forEach(n -> System.out.println(n));
        // Lambda 表达式排序
        List<String> names = Arrays.asList("John", "Jane", "Adam");
        Collections.sort(names, (a, b) -> a.compareTo(b));
        Collections.sort(names);
        //使用 Lambda 表达式作为方法参数
        // 使用 Lambda 表达式调用 process 方法
        process(Arrays.asList("hello", "world"), s -> s.length());

    }
    public static void process(List<String> list, Function<String, Integer> function) {
        for (String item : list) {
            int result = function.apply(item);
            System.out.println(result);
        }
    }
}
